﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Linq.Dynamic;
using LINQtoSQLDataProvider;

namespace Dragon.Prototype1.Service
{
    public class DepartmentService
    {

        static WMSDataContext shareddb;
 
        public static IEnumerable<Department> GetRootDepartments()
        {
            shareddb = new WMSDataContext();
            return shareddb.Departments.Where(p => p.ParentDepartmentID == null).AsEnumerable();            
        }

        public static void DisposeDataContext()
        {
            if (shareddb!=null)
            {
                shareddb.Dispose();
            }
        }

        public static int CreateDepartment(string departname, int parentid)
        { 
            using(WMSDataContext db = new WMSDataContext())
            {
                Department obj=new Department();
                obj.DepartName = departname;
                obj.ParentDepartmentID=parentid;
                db.Departments.InsertOnSubmit(obj);
                db.SubmitChanges();
                return obj.DepartmentID;
            }
        }

        public static bool RenameDepartment(int id, string departname)
        {
            using (WMSDataContext db = new WMSDataContext())
            {
                try
                {
                    Department obj = db.Departments.Single(p => p.DepartmentID == id);
                    obj.DepartName = departname;
                    db.SubmitChanges();
                    return true;
                }
                catch (ChangeConflictException)
                {
                    return false;
                }
            }            
        }

        public static bool DeleteDepartment(int id)
        {
            using (WMSDataContext db = new WMSDataContext())
            {
                try
                {
                    Department obj = db.Departments.Single(p => p.DepartmentID == id);
                    db.Departments.DeleteOnSubmit(obj);
                    db.SubmitChanges();
                    return true;
                }
                catch (ChangeConflictException)
                {
                    return false;
                }
            }                        
        }

        public static IQueryable<User> GetUsersInDepartment(int id, string sidx, string sord)
        {
            WMSDataContext db = new WMSDataContext();
            
            Department department= db.Departments.Single(p => p.DepartmentID == id);
            var users = (from relation in department.DepartmentUserRelationships
                  select relation.User).AsQueryable();

            if(!string.IsNullOrEmpty(sidx))
            {
                if(sidx=="username")
                    users=users.OrderBy(string.Format("{0} {1}",sidx,sord));
                else
                    users = users.OrderBy(string.Format("Membership.{0} {1}", sidx, sord));
            }
            return users;
        }

        /// <summary>
        /// Set user to Unassigned without remove operation
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public static bool SetUnassignedUser(Guid userid)
        {
            using (WMSDataContext db = new WMSDataContext())
            {
                Department department = db.Departments.Single(p => p.DepartName.ToLower() == "unassigned users");
                DepartmentUserRelationship newRelation=new DepartmentUserRelationship();
                newRelation.UserID = userid;
                newRelation.Department=department;
                db.DepartmentUserRelationships.InsertOnSubmit(newRelation);
                db.SubmitChanges();
                return true;
            }
        }

        /// <summary>
        /// Set users to Unassigned User department and remove them from other departments
        /// </summary>
        /// <param name="userids"></param>
        /// <returns></returns>
        public static bool SetUnassignedUsers(Guid[] userids)
        {
            using (WMSDataContext db = new WMSDataContext())
            {
                try
                {
                    var relations = (from relation in db.DepartmentUserRelationships
                                     where userids.Contains(relation.UserID)
                                     select relation).AsEnumerable();
                    db.DepartmentUserRelationships.DeleteAllOnSubmit(relations);

                    Department department = db.Departments.Single(p => p.DepartName.ToLower() == "unassigned users");
                    foreach (Guid userid in userids)
                    {
                        DepartmentUserRelationship newRelation = new DepartmentUserRelationship();
                        newRelation.UserID = userid;
                        newRelation.Department = department;
                        db.DepartmentUserRelationships.InsertOnSubmit(newRelation);
                    }
                    db.SubmitChanges();
                    return true;
                }
                catch (ChangeConflictException)
                {
                    return false;
                }
            }
        }

        public static List<usp_Department_AddUsersToDepartmentResult> AssignUsersToDepartment(Guid[] userids, int newDepartmentID)
        {
                StringBuilder sb = new StringBuilder();
                sb.Append("<ROOT>");
                foreach (Guid userid in userids)
                    sb.AppendFormat("<USER ID=\"{0}\"/>", userid.ToString());
                sb.Append("</ROOT>");
                using (WMSDataContext db = new WMSDataContext())
                {
                    return db.usp_Department_AddUsersToDepartment(sb.ToString(), newDepartmentID).ToList<usp_Department_AddUsersToDepartmentResult>();
                }
        
        }

        public static bool MoveUsersBetweenDepartments(Guid[] userids, int nextDepartmentID, int prevDepartmentID)
        {
            using (WMSDataContext db = new WMSDataContext())
            {
                try{
                    foreach (Guid userid in userids)
                    {
                        //Department department = db.Departments.Single(p => p.DepartmentID == departmentid);
                        DepartmentUserRelationship relation = db.DepartmentUserRelationships.Single(p => p.UserID == userid && p.DepartmentID == prevDepartmentID);
                        if (relation != null)
                        {
                            db.DepartmentUserRelationships.DeleteOnSubmit(relation);
                        }
                        DepartmentUserRelationship newRelation = new DepartmentUserRelationship();
                        newRelation.UserID = userid;
                        newRelation.DepartmentID = nextDepartmentID;
                        db.DepartmentUserRelationships.InsertOnSubmit(newRelation);                        
                    }
                    db.SubmitChanges();
                    return true;
                }           
                catch (ChangeConflictException)
                {
                    return false;
                }
            }
        }
    }
}
